

#include "eg_button.h"

static uint8_t button_state_read_handler(BUTTON_STRUCT* button)
{
	if(button->button_read_state_config_callbakc(button) ==
		button->button_press_state_config){
		return BUTTON_PRESS_STATE;
	}
	else{
		return BUTTON_RELEASE_STATE;
	}
}

static void button_tick_scan_handler(BUTTON_STRUCT* button, uint8_t tick)
{
	uint8_t button_state;
	if(button->button_read_state_config_callbakc != 0){
		button_state = button->button_read_state_config_callbakc(button);
		if(button_state == !(button->button_press_state_config)){
			if(button->last_state == !(button->button_press_state_config)){
				//button free
			}else{
				if(button->press_tick_count >= button->jitter_tick_config){
					if(button->button_release_event_callback != 0){
						button->button_release_event_callback(button);
					}
				}
			}
			button->press_tick_count = 0;
		}
		else{
			if(button->last_state == !(button->button_press_state_config)){
				if(button->press_tick_count == 0){
					if(button->button_press_event_callback != 0){
						button->button_press_event_callback(button);
					}
				}
			}else{
				if(button->press_tick_count >= button->long_press_tick_config){
					if(button->button_long_press_event_callback != 0){
						button->button_long_press_event_callback(button);
					}
					button->press_tick_count -= button->long_press_repeat_tick_config;
				}
			}
			button->press_tick_count += tick;
		}
	}
	button->last_state = button_state;
}

BUTTON_STRUCT* button_new(BUTTON_STRUCT* button)
{
	/**********************************************************/
	//private_attribute
	button->last_state = 0;
	button->press_tick_count = 0;
	/**********************************************************/
	//public_attribute

	/**********************************************************/
	//config_attribute
	button->button_press_state_config = 0;
	button->jitter_tick_config = 0;
	button->long_press_tick_config = 0;
	button->long_press_repeat_tick_config = 0;
	
	/**********************************************************/
	//private_action

	/**********************************************************/
	//public_action
	button->button_tick_scan = button_tick_scan_handler;
	button->button_state_read = button_state_read_handler;
	
	/***********************************************************/
	//config_callbakc
	button->button_init_config_callbakc = 0;
	button->button_read_state_config_callbakc = 0;
	
	/***********************************************************/
	//event_callback
	button->button_press_event_callback = 0;
	button->button_release_event_callback = 0;
	button->button_long_press_event_callback = 0;
}

/*********************************
//how to use
uint8_t n_button_init_config_callbakc_handler(BUTTON_STRUCT* button)
{
	INIT_GPIO_PIN();
	WRITE_GPIO_PIN();
	return 1;
}

uint8_t n_button_read_state_config_callbakc_handler(BUTTON_STRUCT* button)
{
	return READ_GPIO_PIN();
}

void n_button_press_event_callback_handler(BUTTON_STRUCT* button)
{
	LED_ON();
}

void n_button_release_event_callback_handler(BUTTON_STRUCT* button)
{
	LED_OFF();
}

void n_button_long_press_event_callback_handler(BUTTON_STRUCT* button)
{
	LED_TOGGLE();
}

void main(void)
{
	uint8_t tick;
	BUTTON_STRUCT n_button;
	
	button_new(&n_button);
	
	/**********************************************************
	//config_attribute
	n_button.button_press_state_config = GPIO_PIN_LOW_LEVEL;
	n_button.jitter_tick_config = 1;
	n_button.long_press_tick_config = 100;
	n_button.long_press_repeat_tick_config = 50;
	
	/***********************************************************
	//config_callbakc
	n_button.button_init_config_callbakc = n_button_init_config_callbakc_handler;
	n_button.button_read_state_config_callbakc = n_button_read_state_config_callbakc_handler;
	
	/***********************************************************
	//event_callback
	n_button.button_press_event_callback = n_button_press_event_callback_handler;
	n_button.button_release_event_callback = n_button_release_event_callback_handler;
	n_button.button_long_press_event_callback = n_button_long_press_event_callback_handler;
	
	/***********************************************************
	n_button.button_init_config_callbakc(&n_button);
	while(1){
		tick = get_tick();
		n_button.button_tick_scan(&n_button, tick);
	}
}
*********************************/